home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / os2 / remin301.zip / REMIN300.ZIP / CALENDAR.C next >
C/C++ Source or Header  |  1992-11-10  |  23KB  |  796 lines

  1. /***************************************************************/
  2. /*                                                             */
  3. /*  CALENDAR.C                                                 */
  4. /*                                                             */
  5. /*  The code for generating a calendar.                        */
  6. /*                                                             */
  7. /*  This file is part of REMIND.                               */
  8. /*  Copyright (C) 1992 by David F. Skoll.                      */
  9. /*                                                             */
  10. /***************************************************************/
  11. #include "config.h"
  12. #include <stdio.h>
  13. #ifdef HAVE_STDLIB_H
  14. #include <stdlib.h>
  15. #endif
  16. #ifdef HAVE_MALLOC_H
  17. #include <malloc.h>
  18. #endif
  19. #include <ctype.h>
  20. #include "types.h"
  21. #include "protos.h"
  22. #include "expr.h"
  23. #include "globals.h"
  24. #include "err.h"
  25.  
  26. /* Data structures used by the calendar */
  27. typedef struct _cal_entry {
  28.    struct _cal_entry *next;
  29.    char *text;
  30.    char *pos;
  31.    int time;
  32. } CalEntry;
  33.  
  34. /* Global variables */
  35. static CalEntry *CalColumn[7];
  36.  
  37. static int ColSpaces;
  38.  
  39. PRIVATE void SortColByTime ARGS((int col));
  40. PRIVATE void DoCalendarOneWeek ARGS ((void));
  41. PRIVATE void DoCalendarOneMonth ARGS ((void));
  42. PRIVATE int WriteCalendarRow ARGS ((void));
  43. PRIVATE void PrintLeft ARGS ((char *s, int width, char pad));
  44. PRIVATE void PrintCentered ARGS ((char *s, int width, char pad));
  45. PRIVATE int WriteOneCalLine ARGS ((void));
  46. PRIVATE int WriteOneColLine ARGS ((int col));
  47. PRIVATE void GenerateCalEntries ARGS ((int col));
  48. PRIVATE void WriteCalHeader ARGS ((void));
  49. PRIVATE void WriteCalTrailer ARGS ((void));
  50. PRIVATE int DoCalRem ARGS ((ParsePtr p, int col));
  51. PRIVATE void WriteSimpleEntries ARGS ((int col, int jul));
  52. PRIVATE void WriteSolidCalLine ARGS ((void));
  53. PRIVATE void WriteIntermediateCalLine ARGS ((void));
  54. PRIVATE void WriteCalDays ARGS ((void));
  55.  
  56. /***************************************************************/
  57. /*                                                             */
  58. /*  ProduceCalendar                                            */
  59. /*                                                             */
  60. /*  Main loop for generating a calendar.                       */
  61. /*                                                             */
  62. /***************************************************************/
  63. #ifdef HAVE_PROTOS
  64. PUBLIC void ProduceCalendar(void)
  65. #else
  66. void ProduceCalendar()
  67. #endif
  68. {
  69.    int y, m, d;
  70.  
  71.    ShouldCache = 1;
  72.  
  73.    ColSpaces = (CalWidth - 9) / 7;
  74.    CalWidth = 7*ColSpaces + 8;
  75.  
  76.    if (CalMonths) {
  77.       FromJulian(JulianToday, &y, &m, &d);
  78.       JulianToday = Julian(y, m, 1);   
  79.       while (CalMonths--)
  80.          DoCalendarOneMonth();
  81.       return;
  82.    } else {
  83.       JulianToday -= ((JulianToday+1)%7);
  84.  
  85.       WriteIntermediateCalLine();
  86.       WriteCalDays();
  87.       WriteIntermediateCalLine();
  88.  
  89.       while (CalWeeks--)
  90.          DoCalendarOneWeek();
  91.       return;
  92.    }
  93. }
  94.  
  95. /***************************************************************/
  96. /*                                                             */
  97. /*  DoCalendarOneWeek                                          */
  98. /*                                                             */
  99. /*  Write a calendar for a single week                         */
  100. /*                                                             */
  101. /***************************************************************/
  102. #ifdef HAVE_PROTOS
  103. PRIVATE void DoCalendarOneWeek(void)
  104. #else
  105. static void DoCalendarOneWeek()
  106. #endif
  107. {
  108.    int y, m, d, done, i;
  109.    char buf[81];
  110.    int LinesWritten = 0;
  111.    int OrigJul = JulianToday;
  112.  
  113. /* Fill in the column entries */
  114.    for (i=0; i<7; i++) {
  115.       GenerateCalEntries(i);
  116.       JulianToday++;
  117.    }
  118.  
  119. /* Output the entries */
  120.  
  121. /* Here come the first two lines... */
  122.    putchar('|');
  123.    for (i=0; i<7; i++) {
  124.       FromJulian(OrigJul+i, &y, &m, &d);
  125.       sprintf(buf, "%d %c%c%c ", d, MonthName[m][0], MonthName[m][1], 
  126.                                    MonthName[m][2]);
  127.       if (OrigJul+i == RealToday)                  
  128.          PrintLeft(buf, ColSpaces, '*');
  129.       else
  130.          PrintLeft(buf, ColSpaces, ' ');
  131.       putchar('|');
  132.    }
  133.    putchar('\n');
  134. /*** Take out blank line in weekly calendar display - takes up room
  135.    putchar('|');
  136.    for (i=0; i<7; i++) {
  137.       PrintLeft("", ColSpaces, ' ');
  138.       putchar('|');
  139.    }
  140.    putchar('\n');
  141. ***/
  142. /* Write the body lines */
  143.    done = 0;
  144.    while (!done) {
  145.       done = WriteOneCalLine();
  146.       LinesWritten++;
  147.    }
  148.  
  149. /* Write any blank lines required */
  150.    while (LinesWritten++ < CAL_LINES) {
  151.       putchar('|');
  152.       for (i=0; i<7; i++) {
  153.          PrintLeft("", ColSpaces, ' ');
  154.          putchar('|');
  155.       }
  156.       putchar('\n');
  157.    }
  158.  
  159. /* Write the final line */   
  160.    WriteIntermediateCalLine();
  161. }
  162.  
  163. /***************************************************************/
  164. /*                                                             */
  165. /*  DoCalendarOneMonth                                         */
  166. /*                                                             */
  167. /*  Produce a calendar for the current month.                  */
  168. /*                                                             */
  169. /***************************************************************/
  170. #ifdef HAVE_PROTOS
  171. PRIVATE void DoCalendarOneMonth(void)
  172. #else
  173. static void DoCalendarOneMonth()
  174. #endif
  175. {
  176.    if (!DoSimpleCalendar) WriteCalHeader();
  177.  
  178.    while (WriteCalendarRow()) continue;
  179.  
  180.    if (!DoSimpleCalendar) WriteCalTrailer();
  181. }   
  182.  
  183. /***************************************************************/
  184. /*                                                             */
  185. /*  WriteCalendarRow                                           */
  186. /*                                                             */
  187. /*  Write one row of the calendar                              */
  188. /*                                                             */
  189. /***************************************************************/
  190. #ifdef HAVE_PROTOS
  191. PRIVATE int WriteCalendarRow(void)
  192. #else
  193. static int WriteCalendarRow()
  194. #endif
  195. {
  196.    int y, m, d, wd, i;
  197.    int done;
  198.    char buf[81];
  199.    int OrigJul = JulianToday;
  200.    int LinesWritten = 0;
  201.  
  202. /* Get the date of the first day */
  203.    FromJulian(JulianToday, &y, &m, &d);
  204.    wd = (JulianToday + 1) % 7;
  205.  
  206. /* Fill in the column entries */
  207.    for (i=wd; i<7; i++) {
  208.       if (d+i-wd > DaysInMonth(m, y)) break;
  209.       GenerateCalEntries(i);
  210.       JulianToday++;
  211.    }
  212.  
  213. /* Output the entries */
  214.  
  215. /* If it's "Simple Calendar" format, do it simply... */
  216.    if (DoSimpleCalendar) {
  217.       for (i=wd; i<7 && d+i-wd<=DaysInMonth(m, y); i++) {
  218.          WriteSimpleEntries(i, OrigJul+i-wd);
  219.       }
  220.       return (d+7-wd <= DaysInMonth(m, y));
  221.    }
  222.  
  223.  
  224. /* Here come the first two lines... */
  225.    putchar('|');
  226.    for (i=0; i<7; i++) {
  227.       if (i < wd || d+i-wd>DaysInMonth(m, y))
  228.          PrintLeft("", ColSpaces, ' ');
  229.       else {
  230.          sprintf(buf, "%d", d+i-wd);
  231.      PrintLeft(buf, ColSpaces, ' ');
  232.       }
  233.       putchar('|');
  234.    }
  235.    putchar('\n');
  236.    putchar('|');
  237.    for (i=0; i<7; i++) {
  238.       PrintLeft("", ColSpaces, ' ');
  239.       putchar('|');
  240.    }
  241.    putchar('\n');
  242.  
  243. /* Write the body lines */
  244.    done = 0;
  245.    while (!done) {
  246.       done = WriteOneCalLine();
  247.       LinesWritten++;
  248.    }
  249.  
  250. /* Write any blank lines required */
  251.    while (LinesWritten++ < CAL_LINES) {
  252.       putchar('|');
  253.       for (i=0; i<7; i++) {
  254.          PrintLeft("", ColSpaces, ' ');
  255.          putchar('|');
  256.       }
  257.       putchar('\n');
  258.    }
  259.  
  260.    WriteIntermediateCalLine();
  261.  
  262. /* Return non-zero if we have not yet finished */
  263.    return (d+7-wd <= DaysInMonth(m, y));
  264. }
  265.  
  266. /***************************************************************/
  267. /*                                                             */
  268. /*  PrintLeft                                                  */
  269. /*                                                             */
  270. /*  Left-justify a piece of text.                              */
  271. /*                                                             */
  272. /***************************************************************/
  273. #ifdef HAVE_PROTOS
  274. PRIVATE void PrintLeft(char *s, int width, char pad)
  275. #else
  276. static void PrintLeft(s, width, pad)
  277. char *s;
  278. int width;
  279. char pad;
  280. #endif
  281. {
  282.    int len = strlen(s);
  283.    printf("%s", s);
  284.    while (len++ < width) putchar(pad);
  285. }
  286.  
  287. /***************************************************************/
  288. /*                                                             */
  289. /*  PrintCentered                                              */
  290. /*                                                             */
  291. /*  Center a piec of text                                      */
  292. /*                                                             */
  293. /***************************************************************/
  294. #ifdef HAVE_PROTOS
  295. PRIVATE void PrintCentered(char *s, int width, char pad)
  296. #else
  297. static void PrintCentered(s, width, pad)
  298. char *s;
  299. int width;
  300. char pad;
  301. #endif
  302. {
  303.    int len = strlen(s);
  304.    int d = (width - len) / 2;
  305.    int i;
  306.  
  307.    for (i=0; i<d; i++) putchar(pad);
  308.    printf("%s", s);
  309.    for (i=d+len; i<width; i++) putchar(pad);
  310. }
  311.  
  312. /***************************************************************/
  313. /*                                                             */
  314. /*  WriteOneCalLine                                            */
  315. /*                                                             */
  316. /*  Write a single line.                                       */
  317. /*                                                             */
  318. /***************************************************************/
  319. #ifdef HAVE_PROTOS
  320. PRIVATE int WriteOneCalLine(void)
  321. #else
  322. static int WriteOneCalLine()
  323. #endif
  324. {
  325.    int done = 1, i;
  326.  
  327.    putchar('|');
  328.    for (i=0; i<7; i++) {
  329.       if (CalColumn[i]) {
  330.          if (WriteOneColLine(i)) done = 0;
  331.       } else {
  332.          PrintCentered("", ColSpaces, ' ');
  333.       }
  334.       putchar('|');
  335.    }
  336.    putchar('\n');
  337.  
  338.    return done;
  339. }
  340.  
  341.      
  342. /***************************************************************/
  343. /*                                                             */
  344. /*  WriteOneColLine                                            */
  345. /*                                                             */
  346. /*  Write a single line for a specified column.  Return 1 if   */
  347. /*  the column still has entries; 0 otherwise.                 */
  348. /*                                                             */
  349. /***************************************************************/
  350. #ifdef HAVE_PROTOS
  351. PRIVATE int WriteOneColLine(int col)
  352. #else
  353. static int WriteOneColLine(col)
  354. int col;
  355. #endif
  356. {
  357.    CalEntry *e = CalColumn[col];
  358.    char *s;
  359.    char *space;
  360.    int numwritten = 0;
  361.  
  362. /* Print as many characters as possible within the column */
  363.    space = NULL;
  364.    s = e->pos;
  365.  
  366. /* If we're at the end, and there's another entry, do a blank line and move
  367.    to next entry. */
  368.    if (!*s && e->next) {
  369.       PrintLeft("", ColSpaces, ' ');
  370.       CalColumn[col] = e->next;
  371.       free(e->text);
  372.       free(e);
  373.       return 1;
  374.    }
  375.  
  376. /* Find the last space char within the column. */
  377.    while (s - e->pos <= ColSpaces) {
  378.       if (!*s) {space = s; break;}
  379.       if (*s == ' ') space = s;
  380.       s++;
  381.    }
  382.  
  383. /* If we couldn't find a space char, print what we have. */
  384.    if (!space) {
  385.       for (s = e->pos; s - e->pos < ColSpaces; s++) {
  386.          if (!*s) break;
  387.      numwritten++;
  388.          putchar(*s);
  389.       }
  390.       e->pos = s;
  391.    } else {
  392.  
  393. /* We found a space - print everything before it. */
  394.       for (s = e->pos; s<space; s++) {
  395.          if (!*s) break;
  396.      numwritten++;
  397.      putchar(*s);
  398.       }
  399.    }
  400.  
  401. /* Flesh out the rest of the column */
  402.    while(numwritten++ < ColSpaces) putchar(' ');
  403.  
  404. /* Skip any spaces before next word */
  405.    while (*s == ' ') s++;
  406.  
  407. /* If done, free memory if no next entry. */
  408.    if (!*s && !e->next) {
  409.       CalColumn[col] = e->next;
  410.       free(e->text);
  411.       free(e);
  412.    } else {
  413.       e->pos = s;
  414.    }
  415.    if (CalColumn[col]) return 1; else return 0;
  416. }
  417.  
  418. /***************************************************************/
  419. /*                                                             */
  420. /*  GenerateCalEntries                                         */
  421. /*                                                             */
  422. /*  Generate the calendar entries for the ith column           */
  423. /*                                                             */
  424. /***************************************************************/
  425. #ifdef HAVE_PROTOS
  426. PRIVATE void GenerateCalEntries(int col)
  427. #else
  428. static void GenerateCalEntries(col)
  429. int col;
  430. #endif
  431. {
  432.    int r;
  433.    Token tok;
  434.    char *s;
  435.    Parser p;
  436.  
  437. /* Do some initialization first... */
  438.    ClearGlobalOmits();
  439.    DestroyOmitContexts();
  440.    DestroyVars();
  441.  
  442.    r=OpenFile(InitialFile);
  443.    if (r) {
  444.       fprintf(ErrFp, "Can't read %s: %s\n", InitialFile, ErrMsg[r]);
  445.       exit(1);
  446.    }
  447.  
  448.    while(1) {
  449.       r = ReadLine();
  450.       if (r == E_EOF) return;
  451.       if (r) {
  452.      Eprint("Error reading file: %s", ErrMsg[r]);
  453.      exit(1);
  454.       }
  455.       s = FindInitialToken(&tok, CurLine);
  456.  
  457.       /* Should we ignore it? */
  458.       if (NumIfs &&
  459.           tok.type != T_If &&
  460.           tok.type != T_Else &&
  461.           tok.type != T_EndIf &&
  462.           tok.type != T_IfTrig &&
  463.           ShouldIgnoreLine())
  464.       {
  465.       /* DO NOTHING */
  466.       }
  467.       else {
  468.          /* Create a parser to parse the line */
  469.          CreateParser(s, &p);
  470.  
  471.          switch(tok.type) {
  472.  
  473.             case T_Empty:
  474.         case T_Comment:
  475.            break;
  476.  
  477.         case T_ErrMsg:  r=DoErrMsg(&p);  break;
  478.         case T_Rem:     r=DoCalRem(&p, col); break;
  479.         case T_If:      r=DoIf(&p);      break;
  480.         case T_IfTrig:  r=DoIfTrig(&p);  break;
  481.         case T_Else:    r=DoElse(&p);    break;
  482.         case T_EndIf:   r=DoEndif(&p);   break;
  483.         case T_Include: r=DoInclude(&p); break;
  484.         case T_Exit:    exit(99);
  485.         case T_Set:     r=DoSet(&p);     break;
  486.         case T_Fset:    r=DoFset(&p);    break;
  487.         case T_UnSet:   r=DoUnset(&p);   break;
  488.         case T_Clr:     r=DoClear(&p);   break;
  489.             case T_Debug:   break;  /* IGNORE DEBUG CMD */
  490.         case T_Dumpvars: break; /* IGNORE DUMPVARS CMD */
  491.         case T_Banner:  break;  /* IGNORE BANNER CMD */
  492.         case T_Omit:    r=DoOmit(&p);
  493.                        if (r == E_PARSE_AS_REM) {
  494.                    DestroyParser(&p);
  495.                    CreateParser(s, &p);
  496.                    r=DoCalRem(&p, col);
  497.                 }
  498.                             break;
  499.         case T_Pop:     r=PopOmitContext(&p);     break;
  500.         case T_Push:    r=PushOmitContext(&p);    break;
  501.             case T_Preserve: r=DoPreserve(&p);        break;
  502.         case T_RemType: if (tok.val == RUN_TYPE) {
  503.                                r=DoRun(&p);
  504.                                break;
  505.                  } else {
  506.                     CreateParser(CurLine, &p);
  507.                 r=DoCalRem(&p, col);
  508.                 break;
  509.                  }
  510.  
  511.      /* If we don't recognize the command, do a REM by default */
  512.      /* Note:  Since the parser hasn't been used yet, we don't */
  513.      /* need to destroy it here. */
  514.  
  515.         default:        CreateParser(CurLine, &p);
  516.                 r=DoCalRem(&p, col);
  517.                 break;
  518.          }
  519.          if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", ErrMsg[r]);
  520.  
  521.          /* Destroy the parser - free up resources it may be tying up */
  522.          DestroyParser(&p);
  523.       }
  524.    }
  525. }
  526.  
  527.  
  528. /***************************************************************/
  529. /*                                                             */
  530. /*  WriteCalHeader                                             */
  531. /*                                                             */
  532. /***************************************************************/
  533. #ifdef HAVE_PROTOS
  534. PRIVATE void WriteCalHeader(void)
  535. #else
  536. static void WriteCalHeader()
  537. #endif
  538. {
  539.    char buf[80];
  540.    int y, m, d;
  541.  
  542.    FromJulian(JulianToday, &y, &m, &d);
  543.    sprintf(buf, "%s %d", MonthName[m], y);
  544.  
  545.    WriteSolidCalLine();
  546.  
  547.    putchar('|');
  548.    PrintCentered(buf, CalWidth-2, ' ');
  549.    putchar('|');
  550.    putchar('\n');
  551.  
  552.    WriteIntermediateCalLine();
  553.    WriteCalDays();
  554.    WriteIntermediateCalLine();
  555. }
  556.  
  557. /***************************************************************/
  558. /*                                                             */
  559. /*  WriteCalTrailer                                            */
  560. /*                                                             */
  561. /***************************************************************/
  562. #ifdef HAVE_PROTOS
  563. PRIVATE void WriteCalTrailer(void)
  564. #else
  565. static void WriteCalTrailer()
  566. #endif
  567. {
  568.    putchar('\f');
  569. }
  570.  
  571. /***************************************************************/
  572. /*                                                             */
  573. /*  DoCalRem                                                   */
  574. /*                                                             */
  575. /*  Do the REM command in the context of a calendar.           */
  576. /*                                                             */
  577. /***************************************************************/
  578. #ifdef HAVE_PROTOS
  579. PRIVATE int DoCalRem(ParsePtr p, int col)
  580. #else
  581. static int DoCalRem(p, col)
  582. ParsePtr p;
  583. int col;
  584. #endif
  585. {
  586.  
  587.    Trigger trig;
  588.    TimeTrig tim;
  589.    int r;
  590.    int jul;
  591.    CalEntry *CurCol = CalColumn[col];
  592.    CalEntry *e;
  593.    char *s;
  594.  
  595.    /* Parse the trigger date and time */
  596.    if (r=ParseRem(p, &trig, &tim)) return r;
  597.  
  598.    if (trig.typ == NO_TYPE) return E_EOLN;
  599.    if (trig.typ == SAT_TYPE) return DoSatRemind(&trig, &tim, p);
  600.    /* Calculate the trigger date */
  601.    jul = ComputeTrigger(JulianToday, &trig, &r);
  602.    if (r) return r;
  603.  
  604.    /* If trigger date == today, add it to the current entry */   
  605.    if (jul == JulianToday) {
  606.       s = SubstBuffer;
  607.       if (DoSimpleCalendar || tim.ttime != NO_TIME)
  608.          s += strlen(SimpleTime(tim.ttime, s));
  609.       if (r=DoSubst(p, s, &trig, &tim, jul, CAL_MODE)) return r;
  610.       if (!*s) return OK;
  611.       s = SubstBuffer;
  612.       if (!DoSimpleCalendar) while (isspace(*s)) s++;
  613.       e = NEW(CalEntry);
  614.       if (!e) return E_NO_MEM;
  615.       e->text = StrDup(s);
  616.       if (!e->text) {
  617.          free(e);
  618.      return E_NO_MEM;
  619.       }
  620.       e->pos = e->text;
  621.       e->time = tim.ttime;
  622.       e->next = CurCol;
  623.       CalColumn[col] = e;
  624.       SortColByTime(col);
  625.    }
  626.    return OK;
  627. }
  628.  
  629. /***************************************************************/
  630. /*                                                             */
  631. /*  WriteSimpleEntries                                         */
  632. /*                                                             */
  633. /*  Write entries in 'simple calendar' format.                 */
  634. /*                                                             */
  635. /***************************************************************/
  636. #ifdef HAVE_PROTOS
  637. PRIVATE void WriteSimpleEntries(int col, int jul)
  638. #else
  639. static void WriteSimpleEntries(col, jul)
  640. int col, jul;
  641. #endif
  642. {
  643.    CalEntry *e = CalColumn[col];
  644.    CalEntry *n;
  645.    int y, m, d;
  646.  
  647.    FromJulian(jul, &y, &m, &d);
  648.    while(e) {
  649.       printf("%04d/%02d/%02d ", y, m+1, d);
  650.       printf("%s\n", e->text);
  651.       free(e->text);
  652.       n = e->next;
  653.       free(e);
  654.       e = n;
  655.    }
  656.    CalColumn[col] = NULL;
  657. }
  658.  
  659. /***************************************************************/
  660. /*                                                             */
  661. /*  Various functions for writing different types of lines.    */
  662. /*                                                             */
  663. /***************************************************************/
  664. #ifdef HAVE_PROTOS
  665. PRIVATE void WriteSolidCalLine(void)
  666. #else
  667. static void WriteSolidCalLine()
  668. #endif
  669. {
  670.    putchar('+');
  671.    PrintCentered("", CalWidth-2, '-');
  672.    putchar('+');
  673.    putchar('\n');
  674. }
  675.  
  676. #ifdef HAVE_PROTOS
  677. PRIVATE void WriteIntermediateCalLine(void)
  678. #else
  679. static void WriteIntermediateCalLine()
  680. #endif
  681. {
  682.    int i;
  683.  
  684.    putchar('+');
  685.    for (i=0; i<7; i++) {
  686.       PrintCentered("", ColSpaces, '-');
  687.       putchar('+');
  688.    }
  689.    putchar('\n');
  690. }
  691.  
  692. #ifdef HAVE_PROTOS
  693. PRIVATE void WriteCalDays(void)
  694. #else
  695. static void WriteCalDays()
  696. #endif
  697. {
  698.    int i;
  699.    putchar('|');
  700.    for (i=0; i<7; i++) {
  701.       PrintCentered(DayName[(i+6)%7], ColSpaces, ' ');
  702.       putchar('|');
  703.    }
  704.    putchar('\n');
  705. }
  706.  
  707. /***************************************************************/
  708. /*                                                             */
  709. /*  SimpleTime                                                 */
  710. /*                                                             */
  711. /*  Format the time according to simple time format.           */
  712. /*  If out is NULL, result placed in internal static buffer.   */
  713. /*  A trailing space is always added.                          */
  714. /*                                                             */
  715. /***************************************************************/
  716. #ifdef HAVE_PROTOS
  717. PUBLIC char *SimpleTime(int tim, char *out)
  718. #else
  719. char *SimpleTime(tim, out)
  720. int tim;
  721. char *out;
  722. #endif
  723. {
  724.    static buf[9];
  725.    int h, min, hh;
  726.    
  727.    if (!out) out = (char *) buf;
  728.  
  729.    *out = 0;
  730.    
  731.    switch(ScFormat) {
  732.  
  733.       case SC_AMPM:
  734.      if (tim == NO_TIME) sprintf(out, "        ");
  735.      else {
  736.         h = tim / 60;
  737.         min = tim % 60;
  738.         if (h == 0) hh=12;
  739.         else if (h > 12) hh=h-12;
  740.         else hh=h;
  741.         sprintf(out, "%2d:%02d%s ", hh, min, (h>=12) ? "pm" : "am");
  742.          }
  743.      break;
  744.  
  745.       case SC_MIL:
  746.      if (tim == NO_TIME) sprintf(out, "      ");
  747.      else {
  748.         h = tim / 60;
  749.         min = tim % 60;
  750.         sprintf(out, "%02d:%02d ", h, min);
  751.          }
  752.      break;
  753.    }
  754.    return out;
  755. }
  756.  
  757. /***************************************************************/
  758. /*                                                             */
  759. /*  SortColByTime                                              */
  760. /*                                                             */
  761. /*  Sort the calendar entries in a column by time.             */
  762. /*                                                             */
  763. /***************************************************************/
  764. #ifdef HAVE_PROTOS
  765. PRIVATE void SortColByTime(int col)
  766. #else
  767. static void SortColByTime(col)
  768. int col;
  769. #endif
  770. {
  771.    CalEntry *cur, *prev, *next;
  772.  
  773.    cur = CalColumn[col];
  774.    prev = NULL;
  775.  
  776. /* Note that we use >= comparison rather than > comparison to preserve the
  777.    file order of reminders which have the same time! */
  778.  
  779.    while (cur->next && cur->time >= cur->next->time) {
  780.       next = cur->next;
  781.    /* Swap cur and next */
  782.       if (!prev) {
  783.          CalColumn[col] = next;
  784.      cur->next = next->next;
  785.      next->next = cur;
  786.      prev = next;
  787.       } else {
  788.          prev->next = next;
  789.      cur->next = next->next;
  790.      next->next = cur;
  791.      prev = next;
  792.       }
  793.    }
  794. }
  795.  
  796.